/**
 * Copyright(c)2013 Beijing PeaceMap Co.,Ltd.
 * All right reserved. 
 */
package com.pmc.dwa.common.utils.handler;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.io.FilenameUtils;

import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifImage;
import com.gif4j.GifTransformer;
import com.pmc.dwa.common.exception.PmcRuntimeException;
import com.pmc.dwa.common.utils.jhlabs.PmcCropFilter;
import com.pmc.dwa.common.utils.jhlabs.PmcScaleFilter;
import com.pmc.dwa.common.utils.jhlabs.RotateFilter;

/**
 * @description 图片处理类
 * @author aokunsang
 * @date 2013-3-19
 */
public class PmcImageHandler implements ImageHandler {

	public static void main(String[] args) {
		PmcImageHandler handler = new PmcImageHandler();
		handler.crop(new File("D://1.jpg"), new File("D://4.jpg"), 45, 32, 300, 70, 400, 100);
//		handler.rotate(new File("D://1.jpg"), new File("D://2.jpg"), 90);
	}
	
	@Override
	public void crop(File src, File dest, int left, int top, int width,
			int height, int w, int h) throws PmcRuntimeException {
		if(!dest.getParentFile().exists())
			dest.getParentFile().mkdirs();
		try{
			String ext = FilenameUtils.getExtension(dest.getName()).toLowerCase();
			BufferedImage bi = (BufferedImage)ImageIO.read(src);
			height = Math.min(height, bi.getHeight());
			width = Math.min(width, bi.getWidth());
			if(height <= 0) height = bi.getHeight();
			if(width <= 0) width = bi.getWidth();
			top = Math.min(Math.max(0, top), bi.getHeight()-height);
			left = Math.min(Math.max(0, left), bi.getWidth()-width);
			
			if(top==0&&left==0&&width==bi.getWidth()&&height==bi.getHeight()){
				PmcScaleFilter scale = new PmcScaleFilter(w,h);
				BufferedImage bi_scale = new BufferedImage(w,h, (bi.getType()!=0)?bi.getType():BufferedImage.TYPE_INT_RGB);
				scale.filter(bi, bi_scale);
				ImageIO.write(bi_scale, ext.equals("png")?"png":"jpeg", dest);
			}
			else{
				BufferedImage bi_crop = new BufferedImage(width,height, (bi.getType()!=0)?bi.getType():BufferedImage.TYPE_INT_RGB);				
				new PmcCropFilter(left,top,width,height).filter(bi, bi_crop);
				BufferedImage bi_scale = new BufferedImage(w,h, (bi.getType()!=0)?bi.getType():BufferedImage.TYPE_INT_RGB);				
				new PmcScaleFilter(w, h).filter(bi_crop, bi_scale);
				ImageIO.write(bi_scale, ext.equals("png")?"png":"jpeg", dest);
			}
		}catch(IOException e){
			throw new PmcRuntimeException("Exception occur when crop image.", e);
		}
	}

	@Override
	public void rotate(File src, File dest, double degrees)
			throws PmcRuntimeException {
		if(!dest.getParentFile().exists())
			dest.getParentFile().mkdirs();

		try{
			String ext = FilenameUtils.getExtension(dest.getName()).toLowerCase();
			if ("gif".equalsIgnoreCase(ext)) {
				GifImage gifImage = GifDecoder.decode(src);
				GifImage newGif = GifTransformer.rotate(gifImage, degrees, false);
				GifEncoder.encode(newGif, dest);
			} else {
				BufferedImage bi = (BufferedImage)ImageIO.read(src);
				RotateFilter Rotate = new RotateFilter((float)Math.toRadians(degrees));
				BufferedImage bi_rotate = new BufferedImage(bi.getHeight(),bi.getWidth(), (bi.getType()!=0)?bi.getType():BufferedImage.TYPE_INT_RGB);
				Rotate.filter(bi, bi_rotate);
				ImageIO.write(bi_rotate, ext.equals("png")?"png":"jpeg", dest);
			}
		}catch(IOException e){
			throw new PmcRuntimeException("Exception occur when scaling image.", e);
		}
	}

	@Override
	public byte[] scale(File src, int w, int h)
			throws PmcRuntimeException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try{
			if(w <= 0 && h <= 0){
				return null;
			}
			String ext = FilenameUtils.getExtension(src.getName()).toLowerCase();
			if ("gif".equalsIgnoreCase(ext)) {
				GifImage gifImage = GifDecoder.decode(src);
				GifImage newGif = GifTransformer.resize(gifImage, w, h, false);
				GifEncoder.encode(newGif, baos);
			}else{
				BufferedImage bi = (BufferedImage)ImageIO.read(src);
				PmcScaleFilter scale = new PmcScaleFilter(w,h);
				BufferedImage bi_scale = new BufferedImage(w,h, (bi.getType()!=0)?bi.getType():BufferedImage.TYPE_INT_RGB);
				scale.filter(bi, bi_scale);
				ImageIO.write(bi_scale, ext.equals("png")?"png":"jpeg", baos);
			}
			byte[] bytarry = baos.toByteArray();
			baos.flush();
			return bytarry;
		}catch(IOException e){
			throw new PmcRuntimeException("Exception occur when scaling image.", e);
		}finally{
			try {
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
